package globalVisionEntertainment.nba;

import gqqnbig.swing.AutoCompleteTextField;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

import javax.swing.*;

public class MainFrame extends JFrame implements WindowListener, ActionListener
{

	static
	{
		try
		{
			Class.forName("com.mysql.jdbc.Driver");
		}
		catch (ClassNotFoundException e)
		{
			e.printStackTrace();
			System.exit(1);
		}
	}

	public final AutoCompleteTextField[] homeStarterComboBoxes;
	public final AutoCompleteTextField[] visitorStarterComboBoxes;

	public final AutoCompleteTextField[] homeBenchComboBoxes;
	public final AutoCompleteTextField[] visitorBenchComboBoxes;

	public final JTextField dateTextField;
	private final AutoCompleteTextField homeTextField;
	private final AutoCompleteTextField visitorTextField;
	private final JButton readPlayersButton;

	private Connection connection;
	private final JButton matchBenchButton;
	private PlayerPairFrame playerPairFrame;

	public MainFrame()
	{
		super("NBA Game Score Predictor");

		try
		{
			connection = Database.getConnection();
		}
		catch (Exception e)
		{
			throw new RuntimeException(e);
		}
		// setSize(500, 400);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		Container pane = getContentPane();
		pane.setLayout(new BorderLayout());

		ArrayList<String> teamNames = getTeamNames();

		JPanel p = new JPanel();
		p.add(new JLabel("Visitor"));
		visitorTextField = new AutoCompleteTextField(teamNames);
		visitorTextField.setPreferredSize(new Dimension(100, 20));
		p.add(visitorTextField);
		p.add(new JLabel("Home"));
		homeTextField = new AutoCompleteTextField(teamNames);
		homeTextField.setPreferredSize(new Dimension(100, 20));
		p.add(homeTextField);
		p.add(new JLabel("Game date"));
		dateTextField = new JTextField();
		p.add(dateTextField);
		readPlayersButton = new JButton("Read Players");
		readPlayersButton.addActionListener(this);
		p.add(readPlayersButton);

		if (System.getProperty("debug", "false").equals("true"))
		{
			visitorTextField.setText("Thunder");
			homeTextField.setText("Heat");
			dateTextField.setText("2012-06-19");
		}

		pane.add(p, BorderLayout.NORTH);

		Container mainPane = new Container();
		mainPane.setLayout(new GridLayout(0, 2, 20, 20));

		mainPane.add(new JLabel("Home Team Starters"));
		mainPane.add(new JLabel("Visitor Team Starters"));

		ArrayList<String> playerNames = getPlayerNames();

		homeStarterComboBoxes = new AutoCompleteTextField[5];
		visitorStarterComboBoxes = new AutoCompleteTextField[5];

		for (int i = 0; i < homeStarterComboBoxes.length; i++)
		{
			homeStarterComboBoxes[i] = new AutoCompleteTextField(playerNames);
			homeStarterComboBoxes[i].setPreferredSize(new Dimension(200, 20));

			visitorStarterComboBoxes[i] = new AutoCompleteTextField(playerNames);
			visitorStarterComboBoxes[i].setPreferredSize(new Dimension(200, 20));
		}

		for (int i = 0; i < homeStarterComboBoxes.length; i++)
		{
			p = new JPanel();
			p.add(homeStarterComboBoxes[i]);
			mainPane.add(p);

			p = new JPanel();
			p.add(visitorStarterComboBoxes[i]);
			mainPane.add(p);
		}

		mainPane.add(new JLabel("Home Team Bench"));
		mainPane.add(new JLabel("Visitor Team Bench"));
		homeBenchComboBoxes = new AutoCompleteTextField[5];
		visitorBenchComboBoxes = new AutoCompleteTextField[5];

		for (int i = 0; i < homeBenchComboBoxes.length; i++)
		{
			homeBenchComboBoxes[i] = new AutoCompleteTextField(playerNames);
			homeBenchComboBoxes[i].setPreferredSize(new Dimension(200, 20));
			p = new JPanel();
			p.add(homeBenchComboBoxes[i]);
			mainPane.add(p);

			visitorBenchComboBoxes[i] = new AutoCompleteTextField(playerNames);
			visitorBenchComboBoxes[i].setPreferredSize(new Dimension(200, 20));
			p = new JPanel();
			p.add(visitorBenchComboBoxes[i]);
			mainPane.add(p);
		}

		matchBenchButton = new JButton("Match Players");
		matchBenchButton.addActionListener(this);

		mainPane.add(matchBenchButton);

		pane.add(mainPane, BorderLayout.CENTER);

		this.addWindowListener(this);

	}

	private ArrayList<String> getTeamNames()
	{
		Statement statement;
		try
		{
			statement = connection.createStatement();

			ResultSet resultSet = statement.executeQuery("SELECT home FROM NBA.game group by home order by home");

			ArrayList<String> list = new ArrayList<String>();
			resultSet.beforeFirst();
			while (resultSet.next())
			{
				list.add(resultSet.getString(1));
			}
			return list;
		}
		catch (SQLException e)
		{
			throw new RuntimeException(e);
		}
	}

	private ArrayList<String> getPlayerNames()
	{
		try
		{
			Statement statement = connection.createStatement();
			ResultSet resultSet = statement.executeQuery("select playername from playerstatistic group by PlayerName");

			resultSet.first();

			ArrayList<String> names = new ArrayList<String>();
			do
			{
				names.add(resultSet.getString(1));
			} while (resultSet.next());

			return names;
		}
		catch (Exception e)
		{
			throw new RuntimeException(e);
		}
	}

	@Override
	public void windowOpened(WindowEvent e)
	{
		if (System.getProperty("debug", String.valueOf(false)).equals(String.valueOf(true)))
		{
			// homeStarterComboBoxes[0].setText("Kenneth Faried");
			// homeStarterComboBoxes[1].setText("Quincy Miller");
			// homeStarterComboBoxes[2].setText("Timofey Mozgov");
			// homeStarterComboBoxes[3].setText("Ty Lawson");
			// homeStarterComboBoxes[4].setText("Randy Foye");
			//
			// visitorStarterComboBoxes[0].setText("Tim Duncan");
			// visitorStarterComboBoxes[1].setText("Kawhi Leonard");
			// visitorStarterComboBoxes[2].setText("Tiago Splitter");
			// visitorStarterComboBoxes[3].setText("Tony Parker");
			// visitorStarterComboBoxes[4].setText("Danny Green");
			//
			// homeBenchComboBoxes[0].setText("Darrell Arthur");
			// homeBenchComboBoxes[1].setText("Anthony Randolph");
			// homeBenchComboBoxes[2].setText("Aaron Brooks");
			// homeBenchComboBoxes[3].setText("Evan Fournier");
			// // homeBenchComboBoxes[4].setText("Jan Vesely");
			//
			// visitorBenchComboBoxes[0].setText("Aron Baynes");
			// visitorBenchComboBoxes[1].setText("Boris Diaw");
			// visitorBenchComboBoxes[2].setText("Austin Daye");
			// visitorBenchComboBoxes[3].setText("Patty Mills");
			// // visitorBenchComboBoxes[4].setText("Marco Belinelli");

		}
		pack();
	}

	@Override
	public void windowClosed(WindowEvent e)
	{
		try
		{
			connection.close();
		}
		catch (SQLException ex)
		{
			throw new RuntimeException(ex);
		}
	}

	//@formatter:off
	@Override
	public void windowClosing(WindowEvent e)	{}


	@Override
	public void windowIconified(WindowEvent e)	{}

	@Override
	public void windowDeiconified(WindowEvent e)	{}

	@Override
	public void windowActivated(WindowEvent e)	{}

	@Override
	public void windowDeactivated(WindowEvent e)	{}
	//@formatter:on

	@Override
	public void actionPerformed(ActionEvent e)
	{
		NbaScorePredictor scorePredictor = new NbaScorePredictor(connection);
		String gameDate = dateTextField.getText();
		if (e.getSource() == matchBenchButton)
		{
			String[] homeStarters = new String[5];
			String[] visitorStarters = new String[5];
			for (int i = 0; i < homeStarters.length; i++)
			{
				homeStarters[i] = homeStarterComboBoxes[i].getText();
				visitorStarters[i] = visitorStarterComboBoxes[i].getText();
			}

			ArrayList<String> homeBench = new ArrayList<String>();
			ArrayList<String> visitorBench = new ArrayList<String>();
			for (int i = 0; i < homeBenchComboBoxes.length; i++)
			{
				String t1 = homeBenchComboBoxes[i].getText();
				String t2 = visitorBenchComboBoxes[i].getText();

				if (t1.length() > 0 && t2.length() > 0)
				{
					homeBench.add(t1);
					visitorBench.add(t2);
				}
			}

			try
			{

				PlayerPairScoreGain[] scoreGains = scorePredictor.getPlayerPairScoreGains(gameDate, homeStarters, visitorStarters,
						homeBench.toArray(new String[0]), visitorBench.toArray(new String[0]));
				double scoreSum = scorePredictor.getPridictedTotalScore(scoreGains, gameDate);

				if (playerPairFrame != null)
					playerPairFrame.dispose();

				playerPairFrame = new PlayerPairFrame(scoreGains);
				playerPairFrame.gameDate = gameDate;
				playerPairFrame.scoreSumLabel.setText(String.format("%.2f", scoreSum));
				playerPairFrame.setVisible(true);
			}
			catch (SQLException | UnsupportedOperationException ex)
			{
				JOptionPane.showMessageDialog(this, ex.getMessage());

			}
		}
		else if (e.getSource() == readPlayersButton)
		{
			PlayerPairScoreGain[] scoreGains = scorePredictor.getPlayerPairScoreGains(homeTextField.getText(), visitorTextField.getText(),
					gameDate);
			for (int i = 0; i < homeStarterComboBoxes.length; i++)
			{
				homeStarterComboBoxes[i].setText(scoreGains[i].homeGain.playerName);
				visitorStarterComboBoxes[i].setText(scoreGains[i].visitorGain.playerName);
			}
			for (int i = 0; i < homeBenchComboBoxes.length && i + 5 < scoreGains.length; i++)
			{
				homeBenchComboBoxes[i].setText(scoreGains[i + 5].homeGain.playerName);
				visitorBenchComboBoxes[i].setText(scoreGains[i + 5].visitorGain.playerName);
			}
		}
	}

}

class Tuple<T1, T2>
{
	public final T1 item1;
	public final T2 item2;

	public Tuple(T1 item1, T2 item2)
	{
		this.item1 = item1;
		this.item2 = item2;
	}

	@Override
	public String toString()
	{
		return "(" + item1 + "," + item2 + ")";
	}

	@Override
	public boolean equals(Object other)
	{
		if (other == null)
		{
			return false;
		}
		if (other == this)
		{
			return true;
		}
		if (!(other instanceof Tuple))
		{
			return false;
		}
		Tuple<T1, T2> other_ = (Tuple<T1, T2>) other;
		return other_.item1 == this.item1 && other_.item2 == this.item2;
	}

	@Override
	public int hashCode()
	{
		final int prime = 31;
		int result = 1;
		result = prime * result + ((item1 == null) ? 0 : item1.hashCode());
		result = prime * result + ((item2 == null) ? 0 : item2.hashCode());
		return result;
	}
}